package com.ldzy.gateway.filter;

import com.ldzy.common.exception.UnauthorizedException;
import com.ldzy.gateway.utils.JwtTool;
import lombok.RequiredArgsConstructor;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

//@Component
@RequiredArgsConstructor
public class AuthGolbalFilter implements GlobalFilter, Ordered {
    private final JwtTool jwtTool;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //请求被拦截后，执行这里，通过之后，才转发到微服务，没有通过，请求返回浏览器
        //1.提取请求地址
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getPath().toString();//请求地址，
        //2.判断是否要拦截
        if(path.contains("/login")){//含有/login表示不需要拦截
            System.out.println("/login");
            return chain.filter(exchange);//放行
        }
        //3.在消息头部提取token
        String token=null;
        List<String> list = request.getHeaders().get("authorization");
        if (list!=null&&list.size()>0){
            token=list.get(0);
        }
        //4.解析token，获取用户信息
        Long userId=null;
        //使用一个自己定义的解析工具来解析token
        try{
            userId = jwtTool.parseToken(token);
        }catch (UnauthorizedException e){
            //解析失败，终止请求，返回401
            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete();//终止请求，返回浏览器
        }
        //5.携带用户信息转发请求到目标微服务
        //在原有的请求信息基础上添加头部
        String id=userId.toString();
        ServerWebExchange swq=exchange.mutate().
                request(builder -> builder.header("user-info",id)).build();
        return chain.filter(swq);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
